﻿using Shinva.Variables.Helper;
using Shinva.Variables.Interface;
using Shinva.Variables.Type.combination;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Shinva.Variables.Models
{
    /// <summary>
    /// 这是PLC的局部变量表，最后生成偏移量的时候要调用PlcComplexBase的compileAddr方法
    /// </summary>
    public class NormalVariableTable : PlcComplexBase

    {
        // 继承的字段,可以直接使用
        //成员类型
        //private readonly List<IPlcMember> _members = new List<IPlcMember>();

        // 添加获取成员列表的方法
        //public List<IPlcMember> GetMembers() => _members;


        /// <summary>
        /// 所有变量的字典，用于快速查找，防止重名定义
        /// </summary>
        private readonly Dictionary<string, IPlcMember> _variables = new();
        /// <summary>
        /// 所有变量的字典，用于快速查找，下位机符号（变量名）对应到变量
        /// </summary>
        private readonly Dictionary<string, IPlcMember> _symbol_to_variables = new();

  




        /// <summary>
        /// 变量表中添加变量
        /// </summary>
        /// <param name="variable"></param>
        public void AddVariable(IPlcMember variable)
        {
            RegisterVariable(variable);
            this.AddMember(variable);
        }


        /// <summary>
        /// 在字典中注册一下变量名
        /// </summary>
        /// <param name="variable"></param>
        private void RegisterVariable(IPlcMember variable)
        {
            if (variable == null) return;
            if (_variables.ContainsKey(variable.Name))
                throw new ArgumentException($"变量名称冲突: {variable.Name}");
            // 1. 注册自身（如果是结构体，名称对应整个结构体）
            _variables[variable.Name] = variable;
            variable.FullName = variable.Name;
            variable.Symbol = VariableNameGenerator.Convert(variable.Name);
            _symbol_to_variables[variable.Symbol] = variable;
            // 2. 注册子成员（如果是复杂数据类型，递归注册）
            if (variable is PlcComplexBase pcb)
            {
                foreach (var member in pcb.GetMembers())
                {
                    // 确保名称唯一性（例如：Motor1.Enabled）
                    string fullName = $"{pcb.Name}.{member.Name}";
                    RegisterVariableWithFullName(member, fullName);
                }
            }
        }

        private void RegisterVariableWithFullName(IPlcMember member, string fullName)
        {
            if (_variables.ContainsKey(fullName))
                throw new ArgumentException($"变量名称冲突: {fullName}");

            _variables[fullName] = member;
            member.FullName = fullName;
            member.Symbol = VariableNameGenerator.Convert(member.Name);
            _symbol_to_variables[member.Symbol] = member;
            //复杂数据类型的处理，结构体或数组等       
            if (member is PlcComplexBase pcb)
            {
                foreach (var subMember in pcb.GetMembers())
                {
                    string subFullName = $"{fullName}.{subMember.Name}";
                    RegisterVariableWithFullName(subMember, subFullName);
                }
            }

        }




    }
}
